#ifdef WX_PRECOMP
#include "../wx_pch.h"
#else
#include <wx/wx.h>
#endif //WX_PRECOMP

#include "chassis_utility.h"
#include "../unit_field_description.h"

namespace
{
  const UnitCalculator::FieldEnum ChassisBonusItems[] =
  {
    UnitCalculator::FieldSupportMain,
    UnitCalculator::FieldHitPoints,
    UnitCalculator::FieldLaserDefence,
    UnitCalculator::FieldRocketDefence,
    UnitCalculator::FieldLaserDamage,
    UnitCalculator::FieldLaserAttack,
    UnitCalculator::FieldRocketDamage,
    UnitCalculator::FieldRocketAttack,
    UnitCalculator::FieldDistance,
    UnitCalculator::FieldSpeed,
    UnitCalculator::FieldScanStrength,
    UnitCalculator::FieldStealthLevel,
  };
}

size_t ChassisUtility::GetCellsCount(const ComponentItem& chassisItem, const CellsType& type)
{
  if (chassisItem.ID == 0)
  {
    wxASSERT_MSG(0, wxT("Zero chassis item id"));
    return 0;
  }

  switch (type)
  {
  case CELL_CHASSIS:
    return 1;

  case CELL_FRONT:
    return chassisItem.CellsFront;

  case CELL_SIDE:
    return chassisItem.CellsSide;

  case CELL_STERN:
    return chassisItem.CellsStern;

  case CELL_TRANSPORT:
    return chassisItem.CellsTransport;

  case CELL_EXTERNAL:
    return chassisItem.CellsExternal;

  case CELL_SPECIAL:
    return chassisItem.CellsSpecial;

  default:
    return 0;
  }

  return 0;
}

wxString ChassisUtility::GetBonusString(const ComponentItem& chassisItem)
{
  const size_t bonusCount = GetBonusCount();

  wxString result;
  for (size_t i = 0; i < bonusCount; ++i)
  {
    if (const double value = GetBonusValue(i, chassisItem))
    {
      if (!result.empty())
      {
        result << wxT("\n");
      }
      result += wxString::Format(wxT("%s   %+.0f%%"), GetBonusName(i).c_str(), value);
    }
  }
  return result;
}

size_t ChassisUtility::GetBonusCount()
{
  return sizeof(ChassisBonusItems) / sizeof(ChassisBonusItems[0]);
}

wxString ChassisUtility::GetBonusName(size_t index)
{
  if (index >= GetBonusCount())
  {
    return wxEmptyString;
  }
  if (ChassisBonusItems[index] == UnitCalculator::FieldSupportMain)
  {
    return _("Support price");
  }
  return UnitFieldDescription::GetName(ChassisBonusItems[index]);
}

double ChassisUtility::GetBonusValue(size_t index, const ComponentItem& chassisItem)
{
  if (index >= GetBonusCount())
  {
    wxASSERT(!wxT("Bonus index is too large."));
    return 0.0;
  }

  switch (ChassisBonusItems[index])
  {
  case UnitCalculator::FieldHitPoints: return chassisItem.BonusHitPoints;
  case UnitCalculator::FieldLaserDefence: return chassisItem.BonusLaserDefence;
  case UnitCalculator::FieldRocketDefence: return chassisItem.BonusRocketDefence;
  case UnitCalculator::FieldLaserDamage: return chassisItem.BonusLaserDamage;
  case UnitCalculator::FieldRocketDamage: return chassisItem.BonusRocketDamage;
  case UnitCalculator::FieldLaserAttack: return chassisItem.BonusLaserAttack;
  case UnitCalculator::FieldRocketAttack: return chassisItem.BonusRocketAttack;
  case UnitCalculator::FieldSpeed: return chassisItem.BonusSpeed;
  case UnitCalculator::FieldDistance: return chassisItem.BonusDistance;
  case UnitCalculator::FieldStealthLevel: return chassisItem.BonusInvisible;
  case UnitCalculator::FieldScanStrength: return chassisItem.BonusDetect;
  case UnitCalculator::FieldSupportMain: return chassisItem.BonusSupport;
  default: break;
  }

  wxASSERT(!wxT("Unknown field"));
  return 0.0;
}
